package ace.module.product.core.impl.manager.impl;

import ace.cmp.core.constants.CoreConstant;
import ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.model.SaveContext;
import ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.model.SaveListContext;
import ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.utils.SaveContextUtils;
import ace.cmp.util.AceAssertUtils;
import ace.cmp.util.AceNumberUtils;
import ace.module.common.core.impl.manager.impl.AbstractEntityOfAppManager;
import ace.module.product.api.model.dto.PmsProductAttributeValueDto;
import ace.module.product.api.model.input.PmsProductAttributeValueSaveInput;
import ace.module.product.core.impl.dao.entity.PmsProductAttribute;
import ace.module.product.core.impl.dao.entity.PmsProductAttributeValue;
import ace.module.product.core.impl.dao.entity.PmsSpecAttributeValue;
import ace.module.product.core.impl.dao.repository.PmsProductAttributeValueRepository;
import ace.module.product.core.impl.dao.repository.PmsSpecAttributeValueRepository;
import ace.module.product.core.impl.manager.PmsProductAttributeValueManager;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

/**
 * 商品规格属性值 spring data jdbc querydsl rsql manager implement.
 *
 * @author Caspar
 */
@Slf4j
@AllArgsConstructor
@Component
public class PmsProductAttributeValueManagerImpl
    extends AbstractEntityOfAppManager<PmsProductAttributeValue, Long, PmsProductAttributeValueDto>
    implements PmsProductAttributeValueManager {

  private final PmsSpecAttributeValueRepository pmsSpecAttributeValueRepository;
  private final PmsProductAttributeValueRepository pmsProductAttributeValueRepository;

  @Override
  public SaveListContext<PmsProductAttributeValue> assemblePmsProductSpecAttributeValueSaveListContext(
      SaveContext<PmsProductAttribute> pmsProductAttributeSaveContext,
      List<PmsProductAttributeValueSaveInput> pmsProductAttributeValueSaveInputs) {
    List<SaveContext<PmsProductAttributeValue>> saveContexts = pmsProductAttributeValueSaveInputs
        .stream()
        .map(pmsProductAttributeValueSaveInput -> this.assemblePmsProductAttributeValueSaveContext(
                pmsProductAttributeSaveContext,
                pmsProductAttributeValueSaveInput
            )
        )
        .collect(Collectors.toList());

    return SaveContextUtils.of(saveContexts);
  }

  private SaveContext<PmsProductAttributeValue> assemblePmsProductAttributeValueSaveContext(
      SaveContext<PmsProductAttribute> pmsProductAttributeSaveContext,
      PmsProductAttributeValueSaveInput pmsProductAttributeValueSaveInput
  ) {

    Optional<PmsSpecAttributeValue> pmsSpecAttributeValueOptional = this.getAndCheckPmsProductAttributeValue(pmsProductAttributeValueSaveInput.getSpecAttributeValueId());

    PmsProductAttribute pmsProductAttribute = pmsProductAttributeSaveContext.getData();

    boolean isAdd = pmsProductAttributeSaveContext.isNew() || AceNumberUtils.isNullOrNegativeOrZero(pmsProductAttributeValueSaveInput.getId());
    PmsProductAttributeValue pmsProductAttributeValue = null;
    if (isAdd) {
      pmsProductAttributeValue = PmsProductAttributeValue.builder()
          .id(this.getNewId())
          .pmsAppId(pmsProductAttribute.getPmsAppId())
          .productId(pmsProductAttribute.getId())
          .productAttributeId(pmsProductAttribute.getId())
          .build();
    } else {
      pmsProductAttributeValue = this.pmsProductAttributeValueRepository.findByIdAndPmsAppIdAndProductIdAndProductAttributeIdAndDeleteFlag(
          pmsProductAttributeValueSaveInput.getId(),
          pmsProductAttribute.getPmsAppId(),
          pmsProductAttribute.getProductId(),
          pmsProductAttribute.getId(),
          CoreConstant.DELETE_FLAG_NOT
      );
      AceAssertUtils.isNull(pmsProductAttributeValue, "无法修改商品属性值,[%s]商品属性值不存在", pmsProductAttributeValueSaveInput.getId());
    }
    String value = pmsSpecAttributeValueOptional
        .map(PmsSpecAttributeValue::getValue)
        .orElse(pmsProductAttributeValueSaveInput.getValue());
    Long pmsSpecAttributeValueId = pmsSpecAttributeValueOptional
        .map(PmsSpecAttributeValue::getId)
        .orElse(CoreConstant.ZERO_LONG);
    BeanUtils.copyProperties(pmsProductAttributeValueSaveInput, pmsProductAttributeValue);
    pmsProductAttributeValue.setValue(value);
    pmsProductAttributeValue.setSpecAttributeValueId(pmsSpecAttributeValueId);
    return SaveContextUtils.of(pmsProductAttributeValue, isAdd);
  }

  private Optional<PmsSpecAttributeValue> getAndCheckPmsProductAttributeValue(Long specAttributeValueId) {
    if (AceNumberUtils.isNullOrNegativeOrZero(specAttributeValueId)) {
      return Optional.empty();
    }
    PmsSpecAttributeValue pmsSpecAttributeValue = pmsSpecAttributeValueRepository.getById(specAttributeValueId);
    AceAssertUtils.isNull(pmsSpecAttributeValue, "[%s]规格属性值不存在", specAttributeValueId);
    return Optional.of(pmsSpecAttributeValue);
  }
}
